<template>
  <div id="app">
    <div class="marking-content">
      <marking
        :load-fn="loadFunc"
        :image-load-fn="imageLoadFunc"
        :watermark="watermark"
        @selection-change="handleSelectionChange"
        @marking-contextmenu="handleMarkingContextmenu"
        ref="marking">
        <template #toolbox="{ state }">
          <div class="marking-tool-item" @click="zoomOut" title="缩小">
            <img src="~@/assets/zoomout.png">
          </div>
          <div class="marking-tool-item" @click="zoomIn" title="放大">
            <img src="~@/assets/zoomin.png">
          </div>
          <div class="marking-tool-item" title="选择缩放比例">
            <select v-model="state.scaleType" @change="setScale(state.scaleType)">
              <option value="original">实际大小</option>
              <option value="page">适合页面</option>
              <option value="page-fit">适合页宽</option>
              <option :value="0.5">50%</option>
              <option :value="0.75">75%</option>
              <option :value="1">100%</option>
              <option :value="1.25">125%</option>
              <option :value="1.5">150%</option>
              <option :value="2">200%</option>
              <option :value="3">300%</option>
              <option :value="4">400%</option>
              <option :value="state.scaleType" hidden>{{Math.round(state.scaleType*100)}}%</option>
            </select>
          </div>
          <div class="marking-tool-item" @click="clockwise" title="顺时针旋转90°">
            <img src="~@/assets/clockwise.png">
          </div>
          <div class="marking-tool-item" @click="antiClockwise" title="逆时针旋转90°">
            <img src="~@/assets/antiClockwise.png">
          </div>
        </template>
      </marking>
      <div class="selection-toolbar" ref="selectionToolbar" @mousedown.stop>
        <div class="selection-toolbar-item" @click="handleSelectionToolbarItemClick(item)"
             v-for="(item,index) in toolbarList" :key="index">{{item.label}}
        </div>
      </div>
      <div class="selection-contextmenu" ref="selectionContextmenu" @mousedown.stop>
        <div class="selection-contextmenu-item" @click="handleSelectionContextmenuItemClick(item)"
             v-for="(item,index) in contextmenuList" :key="index">{{item.label}}
        </div>
      </div>
    </div>
    <div class="sm" v-if="smShow">
      <div class="container">
        <div class="title">Demo说明</div>
        <div class="content">
          <p>以下为该Demo的一些说明：</p>
          <p>1、Demo显示数据为图片，弱需要支持文本选择需要提供文本数据，数据格式见文件【文件路径：public/data/text1.json】</p>
          <p>2、一些事件说明：</p>
          <p class="second">2.1、【progress】：阅读进度，非加载进度</p>
          <p class="second">2.2、【selection-change】：释放鼠标时存在文本选区，则触发此事件</p>
          <p class="second">2.3、【marking-contextmenu】：此事件参数为{ selection, evt }，当右键时不存在文本选区，selection为null</p>
          <p>3、Demo中的一些小问题（无法处理）：</p>
          <p class="second">3.1、Demo的文本数据是从图片中识别出来的，所以文本坐标不是很准确，导致选区错位</p>
          <p class="second">3.2、页面中是不存在文本的，鼠标的定位点在文本上，鼠标灵敏加上手发抖，导致在鼠标进行点击时候触发了鼠标的move事件，所以选中了文本</p>
          <!--          <p class="second">3.3、至于说滚轮失效：是因为在App.vue页面中弹出菜单时，监听了滚轮事件，进行了阻止，现已改为滚动鼠标滚轮隐藏菜单（与office一致）</p>-->
        </div>
        <div style="text-align: right">
          <button @click="smShow=false">关闭</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import Marking from './components/Marking'

  export default {
    name: 'app',
    data () {
      return {
        smShow: true,
        watermark: {
          text: '这个是水印',
          count: 5,
          color: 'rgba(255,0,0,0.15)',
          fontSize: 200,
          rotation: -30,
          x: 600,
          y: 100,
        },
        toolbarList: [],
        contextmenuList: []
      }
    },
    components: {Marking},
    computed: {
      marking () {
        return this.$refs.marking
      },
      selectionToolbar () {
        return this.$refs.selectionToolbar
      },
      selectionContextmenu () {
        return this.$refs.selectionContextmenu
      },
    },
    mounted () {
      window.addEventListener('keydown', ev => {
        if (ev.ctrlKey && ev.key === 'c') {
          ev.preventDefault()
          ev.stopPropagation()
          this.marking.copySelectText()
          window.alert('已将文本复制到剪贴板')
        }
      })
      // load方法的参数将会在load-fn中传出来
      this.marking.load({desp: '该参数随意传，绑定属性load-fn参数即为该参数'})
    },
    methods: {
      handleSelectionToolbarItemClick (item) {
        if (item.onclick) item.onclick()
        this.hideSelectionToolbar()
      },
      handleSelectionContextmenuItemClick (item) {
        if (item.onclick) item.onclick()
        this.hideSelectionContextmenu()
      },
      handleSelectionChange ({selection, evt}) {
        this.toolbarList = [
          {
            label: '复制文本',
            onclick: () => this.marking.copySelectText()
          },
          {
            label: 'alert文本',
            onclick: () => window.alert(selection.text)
          }
        ]
        this.showSelectionToolbar()
      },
      handleMarkingContextmenu ({selection, evt}) {
        if (selection) {
          this.contextmenuList = [
            {
              label: '复制文本',
              onclick: () => this.marking.copySelectText()
            },
            {
              label: 'alert文本',
              onclick: () => window.alert(selection.text)
            }
          ]
        } else {
          this.contextmenuList = [
            {
              label: '这个是没有选中文本时的右键菜单',
              onclick: () => window.alert('这个是没有选中文本时的右键菜单的点击事件')
            },
            {
              label: '顺时针旋转90°',
              onclick: () => this.marking.clockwise()
            },
            {
              label: '逆时针旋转90°',
              onclick: () => this.marking.antiClockwise()
            },
            {
              label: '调整至实际大小',
              onclick: () => this.marking.setScale('original')
            },
            {
              label: '调整至适合页面',
              onclick: () => this.marking.setScale('page')
            },
            {
              label: '调整至适合页宽',
              onclick: () => this.marking.setScale('page-fit')
            }
          ]
        }
        this.showSelectionContextmenu()
      },
      showSelectionToolbar () {
        this.selectionToolbar.style.top = `${event.pageY - this.selectionToolbar.offsetHeight - 10}px`
        this.selectionToolbar.style.left = `${event.pageX - 30}px`
        this.selectionToolbar.style.visibility = 'visible'
        window.addEventListener("mousedown", this.hideSelectionToolbar)
        window.addEventListener("wheel", this.hideSelectionToolbar, true)
      },
      hideSelectionToolbar () {
        this.selectionToolbar.style.visibility = 'hidden'
        window.removeEventListener("mousedown", this.hideSelectionToolbar)
        window.removeEventListener("wheel", this.hideSelectionToolbar, true)
      },
      showSelectionContextmenu () {
        this.selectionContextmenu.style.top = `${event.pageY - 10}px`
        this.selectionContextmenu.style.left = `${event.pageX + 10}px`
        this.selectionContextmenu.style.visibility = 'visible'
        window.addEventListener("mousedown", this.hideSelectionContextmenu)
        window.addEventListener("wheel", this.hideSelectionContextmenu, true)
      },
      hideSelectionContextmenu () {
        this.selectionContextmenu.style.visibility = 'hidden'
        window.removeEventListener("mousedown", this.hideSelectionContextmenu)
        window.removeEventListener("wheel", this.hideSelectionContextmenu, true)
      },

      async loadFunc (arg) {
        // 该方法用于请求需要加载的数据

        let res1 = await fetch('data/text1.json')

        let text1 = await res1.json()

        let res2 = await fetch('data/text2.json')

        let text2 = await res2.json()

        let res3 = await fetch('data/text3.json')

        let text3 = await res3.json()

        let res4 = await fetch('data/text4.json')

        let text4 = await res4.json()

        let data = [
          {
            page: 0,// 必填
            img: 'test1.jpg', // 必填该值将会在image-load-fn中传出来
            text: text1 // 必填，固定格式{ wrods: [], rows: [] }
          },
          {
            page: 1,
            img: 'test2.jpg',
            text: text2
          },
          {
            page: 2,
            img: 'test3.jpg',
            text: text3
          },
          {
            page: 3,
            img: 'test4.jpg',
            text: text4
          }
        ]

        return {
          data, // 必填(格式固定，参考上面数据格式)
          // markList: [],//非必填
          // pageIndex: 0,// 非必填
        }
      },
      imageLoadFunc (arg) {
        // 该方法为请求图片数据
        // 返回值为图片src（file:///,http://,https://,base64）
        return `data/${arg}`
      },
      zoomOut () {
        this.marking.zoomOut()
      },
      zoomIn () {
        this.marking.zoomIn()
      },
      setScale (scaleType) {
        this.marking.setScale(scaleType)
      },
      clockwise () {
        this.marking.clockwise()
      },
      antiClockwise () {
        this.marking.antiClockwise()
      }
    }
  }
</script>

<style scoped lang="scss">
  #app {
    height: 100vh;
    width: 100vw;
    cursor: default;
    user-select: none;

    .marking-content {
      height: 100%;
      position: relative;

      .marking-tool-item {
        font-size: 14px;
        display: inline-block;
        box-sizing: border-box;
        height: calc(100% - 10px);
        border-radius: 5px;
        margin-top: 5px;
        margin-left: 5px;
        vertical-align: top;

        img {
          box-sizing: border-box;
          padding: 2px;
          height: 100%;
        }

        &:hover {
          background-color: #cccccc;
          color: #fff;
        }

        select {
          height: 100%;
          width: 100%;
          border: none;
          outline: none;
          background-color: transparent;
        }
      }

      .selection-toolbar {
        position: absolute;
        top: 0;
        left: 0;
        background-color: white;
        border-radius: 3px;
        border: 1px solid #ccc;
        visibility: hidden;

        .selection-toolbar-item {
          display: inline-block;
          padding: 0 5px;
          line-height: 30px;
          border-right: 1px solid #ccc;

          &:nth-last-child(1) {
            border-right: none;
          }

          &:hover {
            background-color: #cccccc;
          }
        }

      }

      .selection-contextmenu {
        position: absolute;
        top: 0;
        left: 0;
        background-color: white;
        border-radius: 3px;
        border: 1px solid #ccc;
        visibility: hidden;

        .selection-contextmenu-item {
          text-indent: 20px;
          line-height: 30px;
          padding-right: 10px;
          border-bottom: 1px solid #ccc;

          &:nth-last-child(1) {
            border-bottom: none;
          }

          &:hover {
            background-color: #ccc;
          }
        }
      }
    }

    .sm {
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      background-color: rgba(0, 0, 0, 0.2);

      .container {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 600px;
        background-color: #fff;


        .title {
          text-align: center;
          font-size: 36px;
        }

        .content {
          text-indent: 28px;
          font-size: 14px;
          word-break: break-all;

          .second {
            text-indent: 56px;
          }
        }

      }
    }
  }
</style>

<style>
  html, body {
    margin: 0;
    padding: 0;
  }
</style>
